/**
*******************************************************
*@file  can.c
*@brief can.c
*@author 花满楼
*@date     2020-6-24
*@version  V1
*@attention none
*******************************************************
*/
#include "can.h"
#include "delay.h"
#include "relay_ctl.h"
#include "rs485.h"

///**
//  * @brief  电芯材质
//  */
//typedef enum
//{
//    TERNARY      = 0,  ///<三元锂
//    PHOSPHATE    = 1,  ///<磷酸铁锂
//    COBALT  		 = 2,  ///<钴酸锂
//    MANGANATE    = 3,  ///<锰酸锂
//		TITANATE     = 4	 ///<钛酸锂
//} Cell_Type;

CAN_HandleTypeDef   CAN1_Handler;   //CAN1句柄
CAN_HandleTypeDef   CAN2_Handler;   //CAN2句柄
CanTxMsgTypeDef     TxMessage;      //发送消息
CanRxMsgTypeDef     RxMessage;      //接收消息

/*********************机柜上发信息***************************/
Pack_Message_TypeDef Pack_Message={CELL_NUM,TEMP_PER_NUM*4,TERNARY};	///<存储电芯固定信息
Pack_Mes_TypeDef 	Pack_Mes_Tol;			///<存储电芯综合信息，比如电压、电流
Pack_Rly_TypeDef 	Pack_Rly_Status;	///<存储继电器状态等信息
Pack_Vol_TypeDef  CELL_Vol_Maxi;		///<存储电芯电压和最值信息
Pack_Tem_TypeDef 	Pack_Tem_Maxi;		///<存储温度最值信息
Cell_Vol_TypeDef Cell_Vol_Data[16];	///<存储电芯电压信息，一共4*16=64颗电芯
Cell_Temper_TypeDef Cell_Temper_Data[3];	///<存储电芯温度信息
Cell_Banlance_TypeDef Cell_Banl_Flag;			///<存储电芯均衡标志位
Remain_Mes_TypeDef Remain_Mes;					///<持续充放电时间与容量


u32 reg_time_count;/**<Pack通讯超时计数*/


volatile uint8_t CAN_MsgIndex = 0;
volatile uint8_t CAN2_CanRxMsgFlag = 0; /**<接收到CAN数据后的标志*/
volatile uint8_t CAN1_CanRxMsgFlag = 0; /**<接收到CAN数据后的标志*/

/**
*******************************************************
*@brief CAN初始化
*@param[in]   tsjw:重新同步跳跃时间单元.范围:CAN_SJW_1TQ~CAN_SJW_4TQ
*@param[in]   tbs2:时间段2的时间单元.   范围:CAN_BS2_1TQ~CAN_BS2_8TQ;
*@param[in]   tbs1:时间段1的时间单元.   范围:CAN_BS1_1TQ~CAN_BS1_16TQ
*@param[in]   brp :波特率分频器.范围:1~1024; tq=(brp)*tpclk1
*@param[in]   mode:CAN_MODE_NORMAL,普通模式;CAN_MODE_LOOPBACK,回环模式;
*@param[out]    none
*@return        0,初始化OK;其他,初始化失败;
*@note

    波特率=Fpclk1/((tbs1+tbs2+1)*brp); 其中tbs1和tbs2我们只用关注标识符上标志的序号，例如CAN_BS2_1TQ，我们就认为tbs2=1来计算即可。
    Fpclk1的时钟在初始化的时候设置为45M,如果设置CAN1_Mode_Init(CAN_SJW_1tq,CAN_BS2_6tq,CAN_BS1_7tq,6,CAN_MODE_LOOPBACK);
    则波特率为:42M/((6+7+1)*12)=250Kbps
*******************************************************
 */
u8 CAN1_Mode_Init(u32 tsjw, u32 tbs2, u32 tbs1, u16 brp, u32 mode)
{
	
    CAN_FilterConfTypeDef  CAN1_FilerConf;
    CAN1_Handler.Instance = CAN1;
    CAN1_Handler.pTxMsg = &TxMessage;   //发送消息
    CAN1_Handler.pRxMsg = &RxMessage;   //接收消息
    CAN1_Handler.Init.Prescaler = brp;  //分频系数(Fdiv)为brp+1
    CAN1_Handler.Init.Mode = mode;      //模式设置
    CAN1_Handler.Init.SJW = tsjw;       //重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位 CAN_SJW_1TQ~CAN_SJW_4TQ
    CAN1_Handler.Init.BS1 = tbs1;       //tbs1范围CAN_BS1_1TQ~CAN_BS1_16TQ
    CAN1_Handler.Init.BS2 = tbs2;       //tbs2范围CAN_BS2_1TQ~CAN_BS2_8TQ
    CAN1_Handler.Init.TTCM = DISABLE;   //非时间触发通信模式
    CAN1_Handler.Init.ABOM = DISABLE;   //软件自动离线管理
    CAN1_Handler.Init.AWUM = DISABLE;   //睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位)
    CAN1_Handler.Init.NART = ENABLE;    //禁止报文自动传送
    CAN1_Handler.Init.RFLM = DISABLE;   //报文不锁定,新的覆盖旧的
    CAN1_Handler.Init.TXFP = DISABLE;   //优先级由报文标识符决定

    if (HAL_CAN_Init(&CAN1_Handler) != HAL_OK) return 1;      //初始化

    CAN1_FilerConf.FilterFIFOAssignment = CAN_FILTER_FIFO0; //过滤器0关联到FIFO0
    CAN1_FilerConf.FilterNumber = 0;        //过滤器0
    CAN1_FilerConf.FilterMode = CAN_FILTERMODE_IDMASK;
    CAN1_FilerConf.FilterScale = CAN_FILTERSCALE_32BIT;
    CAN1_FilerConf.FilterActivation = ENABLE; //激活滤波器0
    CAN1_FilerConf.BankNumber = 14;
    CAN1_FilerConf.FilterIdHigh = 0x00; //(((MSG_RECEIVE_ID>>18)&0x7FF)<<5)|((MSG_RECEIVE_ID>>13)&0x1F);
    CAN1_FilerConf.FilterIdLow = 0x00;//((MSG_RECEIVE_ID << 3) | ((MSG_ID_TYPE & 0X01) << 2)) & 0xFFFF;
    CAN1_FilerConf.FilterMaskIdHigh = 0x00;
    CAN1_FilerConf.FilterMaskIdLow = 0x00;//((MSG_RECEIVE_ID << 3) | ((MSG_ID_TYPE & 0X01) << 2)) & 0xFFFF;

    if (HAL_CAN_ConfigFilter(&CAN1_Handler, &CAN1_FilerConf) != HAL_OK) return 2;      //滤波器初始化

    return 0;
}

/**
*******************************************************
*@brief CAN初始化
*@param[in]   tsjw:重新同步跳跃时间单元.范围:CAN_SJW_1TQ~CAN_SJW_4TQ
*@param[in]   tbs2:时间段2的时间单元.   范围:CAN_BS2_1TQ~CAN_BS2_8TQ;
*@param[in]   tbs1:时间段1的时间单元.   范围:CAN_BS1_1TQ~CAN_BS1_16TQ
*@param[in]   brp :波特率分频器.范围:1~1024; tq=(brp)*tpclk1
*@param[in]   mode:CAN_MODE_NORMAL,普通模式;CAN_MODE_LOOPBACK,回环模式;
*@param[out]    none
*@return        0,初始化OK;其他,初始化失败;
*@note

    波特率=Fpclk1/((tbs1+tbs2+1)*brp); 其中tbs1和tbs2我们只用关注标识符上标志的序号，例如CAN_BS2_1TQ，我们就认为tbs2=1来计算即可。
    Fpclk1的时钟在初始化的时候设置为45M,如果设置CAN1_Mode_Init(CAN_SJW_1tq,CAN_BS2_6tq,CAN_BS1_7tq,6,CAN_MODE_LOOPBACK);
    则波特率为:42M/((6+7+1)*12)=250Kbps
*******************************************************
 */
u8 CAN2_Mode_Init(u32 tsjw, u32 tbs2, u32 tbs1, u16 brp, u32 mode)
{
    CAN_FilterConfTypeDef  CAN2_FilerConf;
	
	
    CAN2_Handler.Instance = CAN2;
    CAN2_Handler.pTxMsg = &TxMessage;   //发送消息
    CAN2_Handler.pRxMsg = &RxMessage;   //接收消息
    CAN2_Handler.Init.Prescaler = brp;  //分频系数(Fdiv)为brp+1
    CAN2_Handler.Init.Mode = mode;      //模式设置
    CAN2_Handler.Init.SJW = tsjw;       //重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位 CAN_SJW_1TQ~CAN_SJW_4TQ
    CAN2_Handler.Init.BS1 = tbs1;       //tbs1范围CAN_BS1_1TQ~CAN_BS1_16TQ
    CAN2_Handler.Init.BS2 = tbs2;       //tbs2范围CAN_BS2_1TQ~CAN_BS2_8TQ
    CAN2_Handler.Init.TTCM = DISABLE;   //非时间触发通信模式
    CAN2_Handler.Init.ABOM = DISABLE;   //软件自动离线管理
    CAN2_Handler.Init.AWUM = DISABLE;   //睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位)
    CAN2_Handler.Init.NART = ENABLE;    //禁止报文自动传送
    CAN2_Handler.Init.RFLM = DISABLE;   //报文不锁定,新的覆盖旧的
    CAN2_Handler.Init.TXFP = DISABLE;   //优先级由报文标识符决定

    if (HAL_CAN_Init(&CAN2_Handler) != HAL_OK) return 1;      //初始化


    CAN2_FilerConf.FilterFIFOAssignment = CAN_FILTER_FIFO0; //过滤器0关联到FIFO0
    CAN2_FilerConf.FilterNumber = 14;        //过滤器14
    CAN2_FilerConf.FilterMode = CAN_FILTERMODE_IDMASK;
    CAN2_FilerConf.FilterScale = CAN_FILTERSCALE_32BIT;
    CAN2_FilerConf.FilterActivation = ENABLE; //激活滤波器0
    CAN2_FilerConf.BankNumber = 14;
	CAN2_FilerConf.FilterIdHigh = 0x00; //0XC007;     //32位ID
    CAN2_FilerConf.FilterIdLow = 0x00; //0X8200;
    CAN2_FilerConf.FilterMaskIdHigh = 0x00; //0XC007; //32位MASK
    CAN2_FilerConf.FilterMaskIdLow = 0x00; //0XFA00;

    if (HAL_CAN_ConfigFilter(&CAN1_Handler, &CAN2_FilerConf) != HAL_OK) return 2;      //滤波器初始化

    return 0;
}

/**
*******************************************************
*@brief CAN底层驱动，引脚配置，时钟配置，中断配置
*@param[in]   hcan:CAN句柄
*@return      none
*@note     此函数会被HAL_CAN_Init()调用
*******************************************************
 */
void HAL_CAN_MspInit(CAN_HandleTypeDef *hcan)
{
    GPIO_InitTypeDef GPIO_Initure;
    __HAL_RCC_CAN1_CLK_ENABLE();                //使能CAN1时钟
    __HAL_RCC_GPIOA_CLK_ENABLE();               //开启GPIOA时钟
    __HAL_RCC_CAN2_CLK_ENABLE();                //使能CAN2时钟
    __HAL_RCC_GPIOB_CLK_ENABLE();               //开启GPIOB时钟
    GPIO_Initure.Pin = GPIO_PIN_11 | GPIO_PIN_12; //PA11,12
    GPIO_Initure.Mode = GPIO_MODE_AF_PP;        //推挽复用
    GPIO_Initure.Pull = GPIO_PULLUP;            //上拉
    GPIO_Initure.Speed = GPIO_SPEED_FAST;       //快速
    GPIO_Initure.Alternate = GPIO_AF9_CAN1;     //复用为CAN1
    HAL_GPIO_Init(GPIOA, &GPIO_Initure);        //初始化
    GPIO_Initure.Pin = GPIO_PIN_5 | GPIO_PIN_6; //PB5.6
    GPIO_Initure.Mode = GPIO_MODE_AF_PP;        //推挽复用
    GPIO_Initure.Pull = GPIO_PULLUP;            //上拉
    GPIO_Initure.Speed = GPIO_SPEED_FAST;       //快速
    GPIO_Initure.Alternate = GPIO_AF9_CAN2;     //复用为CAN2
    HAL_GPIO_Init(GPIOB, &GPIO_Initure);        //初始化
#if CAN1_RX0_INT_ENABLE
    __HAL_CAN_ENABLE_IT(&CAN1_Handler, CAN_IT_FMP0);    //FIFO0消息挂起中断允许.
    HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 0, 2);    //抢占优先级0，子优先级2
    HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);          //使能中断
#endif
#if CAN2_RX0_INT_ENABLE
    __HAL_CAN_ENABLE_IT(&CAN2_Handler, CAN_IT_FMP0);    //FIFO0消息挂起中断允许.
    HAL_NVIC_SetPriority(CAN2_RX0_IRQn, 1, 2);    //抢占优先级1，子优先级2
    HAL_NVIC_EnableIRQ(CAN2_RX0_IRQn);          //使能中断
#endif
}

#if CAN1_RX0_INT_ENABLE                         /**使能RX0中断*/

/**
*******************************************************
*@brief CAN中断服务函数
*@param[in]   none
*@return      none
*@note     none
*******************************************************
*/
void CAN1_RX0_IRQHandler(void)
{
    HAL_CAN_IRQHandler(&CAN1_Handler);    //此函数会调用CAN_Receive_IT()接收数据
    Message_Handle(CAN1_Handler.pRxMsg);        //CAN信息处理

    //对接收到的数据先做简单的判断，去掉错误的数据
    if ((CAN1_Handler.pRxMsg->IDE == CAN_ID_STD) && (CAN1_Handler.pRxMsg->DLC == 8))
    {
        CAN1_CanRxMsgFlag = 1;
    }
}

/**
*******************************************************
*@brief CAN1中断处理过程
*@param[in]   hcan:CAN句柄
*@return      none
*@note     此函数会被CAN_Receive_IT()调用
*******************************************************
*/
void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef *hcan)
{
//    int i=0;
    //CAN_Receive_IT()函数会关闭FIFO0消息挂号中断，因此我们需要重新打开
    __HAL_CAN_ENABLE_IT(&CAN1_Handler, CAN_IT_FMP0);    //重新开启FIF00消息挂号中断
    __HAL_CAN_ENABLE_IT(&CAN2_Handler, CAN_IT_FMP0);    //重新开启FIF00消息挂号中断
}
#endif
#if CAN2_RX0_INT_ENABLE                         /**使能RX0中断*/
/**
*******************************************************
*@brief CAN2中断处理过程
*@param[in]   hcan:CAN句柄
*@return      none
*@note     此函数会被CAN_Receive_IT()调用
*******************************************************
*/
void CAN2_RX0_IRQHandler(void)
{
    HAL_CAN_IRQHandler(&CAN2_Handler);    //此函数会调用CAN_Receive_IT()接收数据
    reg_time_count = HAL_GetTick();  //HAL_GetTick()应该是ms，用于判断通讯超时，

    //对接收到的数据先做简单的判断，去掉错误的数据

    if ((CAN2_Handler.pRxMsg->IDE == CAN_ID_STD) && (CAN2_Handler.pRxMsg->DLC == 8))
    {
        CAN2_CanRxMsgFlag = 1;
    }
}
//void CAN2_RX1_IRQHandler(void)
//{
//    HAL_CAN_IRQHandler(&CAN2_Handler);    //此函数会调用CAN_Receive_IT()接收数据
//    reg_time_count = HAL_GetTick();  //HAL_GetTick()应该是ms，用于判断通讯超时，

//    //对接收到的数据先做简单的判断，去掉错误的数据

//    if ((CAN2_Handler.pRxMsg->IDE == CAN_ID_STD) && (CAN2_Handler.pRxMsg->DLC == 8))
//    {
//        CAN2_CanRxMsgFlag = 1;
//    }
//}
#endif

/**
*******************************************************
*@brief can2发送一组数据(固定格式:ID为0X12,标准帧,数据帧)
*@param[in]   len:数据长度(最大为8)
*@return      0,成功;其他,失败;
*@note     此函数会被CAN_Receive_IT()调用
*******************************************************
*/
u8 CAN2_Send_Msg(u8 len)
{
    CAN2_Handler.pTxMsg->ExtId = 0x186040F0;      //扩展标识符(29位)
    CAN2_Handler.pTxMsg->IDE = 4;  //使用标准帧
    CAN2_Handler.pTxMsg->RTR = 0; //数据帧
    CAN2_Handler.pTxMsg->DLC = len;
	
	CAN2_Handler.pTxMsg->Data[0] = 0x00;
	CAN2_Handler.pTxMsg->Data[1] = 0x01;
	CAN2_Handler.pTxMsg->Data[2] = 0x02;
	CAN2_Handler.pTxMsg->Data[3] = 0x03;
	CAN2_Handler.pTxMsg->Data[4] = 0x04;
	CAN2_Handler.pTxMsg->Data[5] = 0x05;
	CAN2_Handler.pTxMsg->Data[6] = 0x06;
	CAN2_Handler.pTxMsg->Data[7] = 0x07;
	
    if (HAL_CAN_Transmit(&CAN2_Handler, 1) != HAL_OK) return 1;      //发送

    return 0;
}

/**
*******************************************************
* @brief  can1发送数据到其他pack或其他上位机
* @param  TxMessage CAN消息指针
* @retval 0-消息发送成功，1-消息发送失败
* @note  
					*一共25帧数据，一次循环（10ms）发送3帧数据，100ms做一个循环
					*调试时需要确认总线负载率，并考虑总执行时间
					*确认static的使用
*******************************************************
*/
void CAN1_SendToPack(u8 Addr)
{
		static u8 send_count=0;	//用于发送计时
		Addr = 0;
	
		send_count++;
		switch(send_count)
		{
			case 1: 
							Pack_Rly_Status.RlyStr.Bit.ChaRlyStr = RELAY_CHARGE;
							Pack_Rly_Status.RlyStr.Bit.DisRlyStr = RELAY_DISCHAR;
							Pack_Rly_Status.RlyStr.Bit.PreRlyStr = RELAY_PRECHAR;
							CAN1_Send_PackMeg(&Pack_Message,M2M_0+Addr, 3);	//确认sizeof的结果是什么
							CAN1_Send_TotMeg(&Pack_Mes_Tol, M2M_1+Addr, 5);
							CAN1_Send_RlyMeg(&Pack_Rly_Status, M2M_2+Addr, 5);
							break;
			case 2:
							CAN1_Send_VolMeg(&CELL_Vol_Maxi, M2M_3+Addr, 8);
							CAN1_Send_TemMeg(&Pack_Tem_Maxi, M2M_4+Addr, 7);
							CAN1_Send_CellV(&Cell_Vol_Data[0], M2M_5+Addr, 8);
							break;
			case 3:
							CAN1_Send_CellV(&Cell_Vol_Data[1], M2M_6+Addr, 8);
							CAN1_Send_CellV(&Cell_Vol_Data[2], M2M_7+Addr, 8);
							CAN1_Send_CellV(&Cell_Vol_Data[3], M2M_8+Addr, 8);
							break;
			case 4:
							CAN1_Send_CellV(&Cell_Vol_Data[4], M2M_9+Addr, 8);
							CAN1_Send_CellV(&Cell_Vol_Data[5], M2M_10+Addr, 8);
							CAN1_Send_CellV(&Cell_Vol_Data[6], M2M_11+Addr, 8);
							break;
			case 5:
							CAN1_Send_CellV(&Cell_Vol_Data[7], M2M_12+Addr, 8);
							CAN1_Send_CellV(&Cell_Vol_Data[8], M2M_13+Addr, 8);
							CAN1_Send_CellV(&Cell_Vol_Data[9], M2M_14+Addr, 8);
							break;
			case 6:
							CAN1_Send_CellV(&Cell_Vol_Data[10], M2M_15+Addr, 8);
							CAN1_Send_CellV(&Cell_Vol_Data[11], M2M_16+Addr, 8);
							CAN1_Send_CellV(&Cell_Vol_Data[12], M2M_17+Addr, 8);
							break;
			case 7:
							CAN1_Send_CellV(&Cell_Vol_Data[13], M2M_18+Addr, 8);
							CAN1_Send_CellV(&Cell_Vol_Data[14], M2M_19+Addr, 8);
							CAN1_Send_CellT(&Cell_Temper_Data[0], M2M_20+Addr, 8);
							break;
			case 8:
							CAN1_Send_CellT(&Cell_Temper_Data[1], M2M_21+Addr, 8);
							CAN1_Send_CellT(&Cell_Temper_Data[2], M2M_22+Addr, 8);
							CAN1_Send_Banl(&Cell_Banl_Flag, M2M_23, 8);
							break;
			case 9:
							CAN1_Send_AlmMeg(&Alarm_Reg, M2M_24+Addr, 8);
							CAN1_Send_RemTimeMeg(&Remain_Mes, M2M_25+Addr, 8);
							CAN1_Send_DebugMsg(&Control_Reg.Control1.Word, 0x1800F040+Addr, 8); 
							break;
			case 10:
							send_count = 0;
							break;
			default: break;
		}
}

/**
*******************************************************
* @brief  can1发送一帧CAN数据
* @param  TxMessage CAN消息指针
* @retval 0-消息发送成功，1-消息发送失败
*******************************************************
*/
uint8_t CAN_WriteData(CanTxMsgTypeDef *TxMessage)
{
    CAN1_Handler.pTxMsg->StdId = TxMessage->StdId;
    CAN1_Handler.pTxMsg->ExtId = TxMessage->ExtId;      //扩展标识符(29位)
    CAN1_Handler.pTxMsg->IDE = TxMessage->IDE;  //使用标准帧
    CAN1_Handler.pTxMsg->RTR = TxMessage->RTR; //数据帧
    CAN1_Handler.pTxMsg->DLC = TxMessage->DLC;
    CAN1_Handler.pTxMsg->Data[0] = TxMessage->Data[0];
    CAN1_Handler.pTxMsg->Data[1] = TxMessage->Data[1];
    CAN1_Handler.pTxMsg->Data[2] = TxMessage->Data[2];
    CAN1_Handler.pTxMsg->Data[3] = TxMessage->Data[3];
    CAN1_Handler.pTxMsg->Data[4] = TxMessage->Data[4];
    CAN1_Handler.pTxMsg->Data[5] = TxMessage->Data[5];
    CAN1_Handler.pTxMsg->Data[6] = TxMessage->Data[6];
    CAN1_Handler.pTxMsg->Data[7] = TxMessage->Data[7];

    if (HAL_CAN_Transmit(&CAN1_Handler, 100) != HAL_OK) return 1;      //发送

    return 0;
}

/**
*******************************************************
*@brief 发送系统pack固有信息，包括电芯数量、温度采集点数量等
*@param[in]   msg：消息指针
*@param[in]   CAN_ID：目标ID
*@param[in]   len:数据长度(最大为8)
*@return      0,成功;其他,失败;
*@note     none
*******************************************************
*/
u8 CAN1_Send_PackMeg(Pack_Message_TypeDef *msg, u32 CAN_ID, u8 len)
{
    CAN1_Handler.pTxMsg->ExtId = CAN_ID;      //扩展标识符(29位)
    CAN1_Handler.pTxMsg->IDE = CAN_ID_EXT;  //使用扩展帧
    CAN1_Handler.pTxMsg->RTR = CAN_RTR_DATA; //数据帧
    CAN1_Handler.pTxMsg->DLC = len;
    CAN1_Handler.pTxMsg->Data[0] = msg->CellNum;
    CAN1_Handler.pTxMsg->Data[1] = msg->TempNum;
    CAN1_Handler.pTxMsg->Data[2] = msg->CellMaterials;

    if (HAL_CAN_Transmit(&CAN1_Handler, 1) != HAL_OK) return 1;      //发送

    return 0;
}

/**
*******************************************************
*@brief 发送系统pack总压、总流等数据
*@param[in]   msg：消息指针
*@param[in]   CAN_ID：目标ID
*@param[in]   len:数据长度(最大为8)
*@return      0,成功;其他,失败;
*@note     none
*******************************************************
*/
u8 CAN1_Send_TotMeg(Pack_Mes_TypeDef *msg, u32 CAN_ID, u8 len)
{
    CAN1_Handler.pTxMsg->ExtId = CAN_ID;      //扩展标识符(29位)
    CAN1_Handler.pTxMsg->IDE = CAN_ID_EXT;  //使用扩展帧
    CAN1_Handler.pTxMsg->RTR = CAN_RTR_DATA; //数据帧
    CAN1_Handler.pTxMsg->DLC = len;
    CAN1_Handler.pTxMsg->Data[0] = msg->Pack_Vol & 0xFF;
		CAN1_Handler.pTxMsg->Data[1] = (msg->Pack_Vol & 0xFF00)>>8;
		CAN1_Handler.pTxMsg->Data[2] = (msg->Pack_Cur + 3000) & 0xFF;
    CAN1_Handler.pTxMsg->Data[3] = ((msg->Pack_Cur + 3000) & 0xFF00) >> 8;	
    CAN1_Handler.pTxMsg->Data[4] = msg->Pack_SOC;
    CAN1_Handler.pTxMsg->Data[5] = msg->Pack_SOH;
    CAN1_Handler.pTxMsg->Data[6] = msg->Pack_Alm;

    if (HAL_CAN_Transmit(&CAN1_Handler, 1) != HAL_OK) return 1;      //发送

    return 0;
}

/**
*******************************************************
*@brief 发送继电器等状态信息
*@param[in]   msg：消息指针
*@param[in]   CAN_ID：目标ID
*@param[in]   len:数据长度(最大为8)
*@return      0,成功;其他,失败;
*@note     none
*******************************************************
*/
u8 CAN1_Send_RlyMeg(Pack_Rly_TypeDef *msg, u32 CAN_ID, u8 len)
{
    CAN1_Handler.pTxMsg->ExtId = CAN_ID;      //扩展标识符(29位)
    CAN1_Handler.pTxMsg->IDE = CAN_ID_EXT;  //使用扩展帧
    CAN1_Handler.pTxMsg->RTR = CAN_RTR_DATA; //数据帧
    CAN1_Handler.pTxMsg->DLC = len;
    CAN1_Handler.pTxMsg->Data[0] = msg->BatState;
    CAN1_Handler.pTxMsg->Data[1] = msg->RlyStr.Byte;
    CAN1_Handler.pTxMsg->Data[2] = msg->BatLife;
    CAN1_Handler.pTxMsg->Data[3] = msg->SocHistory;
    CAN1_Handler.pTxMsg->Data[4] = msg->SohHistory;

    if (HAL_CAN_Transmit(&CAN1_Handler, 1) != HAL_OK) return 1;      //发送

    return 0;
}

/**
*******************************************************
*@brief 发送机柜中电芯电压最大值最小值以及对应的编号
*@param[in]   msg：消息指针
*@param[in]   CAN_ID：目标ID
*@param[in]   len:数据长度(最大为8)
*@return      0,成功;其他,失败;
*@note     none
*******************************************************
*/
u8 CAN1_Send_VolMeg(Pack_Vol_TypeDef *msg, u32 CAN_ID, u8 len)
{
    CAN1_Handler.pTxMsg->ExtId = CAN_ID;      //扩展标识符(29位)
    CAN1_Handler.pTxMsg->IDE = CAN_ID_EXT;  //使用扩展帧
    CAN1_Handler.pTxMsg->RTR = CAN_RTR_DATA; //数据帧
    CAN1_Handler.pTxMsg->DLC = len;
    CAN1_Handler.pTxMsg->Data[0] = msg->Max_Cell_Volt & 0xFF;
    CAN1_Handler.pTxMsg->Data[1] = (msg->Max_Cell_Volt & 0xFF00) >> 8;
    CAN1_Handler.pTxMsg->Data[2] = msg->Min_Cell_Volt & 0xFF;
    CAN1_Handler.pTxMsg->Data[3] = (msg->Min_Cell_Volt & 0xFF00) >> 8;
    CAN1_Handler.pTxMsg->Data[4] = msg->Max_Volt_Module;
    CAN1_Handler.pTxMsg->Data[5] = msg->Max_Volt_No;
    CAN1_Handler.pTxMsg->Data[6] = msg->Min_Volt_Module;
    CAN1_Handler.pTxMsg->Data[7] = msg->Min_Volt_No;

    if (HAL_CAN_Transmit(&CAN1_Handler, 1) != HAL_OK) return 1;      //发送

    return 0;
}

/**
*******************************************************
*@brief 发送机柜中电芯温度最大值最小值以及对应的编号，以及±母线电阻和继电器状态
*@param[in]   msg：消息指针
*@param[in]   CAN_ID：目标ID
*@param[in]   len:数据长度(最大为8)
*@return      0,成功;其他,失败;
*@note     none
*******************************************************
*/
u8 CAN1_Send_TemMeg(Pack_Tem_TypeDef *msg, u32 CAN_ID, u8 len)
{
    CAN1_Handler.pTxMsg->ExtId = CAN_ID;      //扩展标识符(29位)
    CAN1_Handler.pTxMsg->IDE = CAN_ID_EXT;  //使用扩展帧
    CAN1_Handler.pTxMsg->RTR = CAN_RTR_DATA; //数据帧
    CAN1_Handler.pTxMsg->DLC = len;
    CAN1_Handler.pTxMsg->Data[0] = (msg->Max_Cell_Tem);
    CAN1_Handler.pTxMsg->Data[1] = (msg->Min_Cell_Tem);
    CAN1_Handler.pTxMsg->Data[2] = msg->Max_Tem_Module;
    CAN1_Handler.pTxMsg->Data[3] = msg->Max_Tem_No;
    CAN1_Handler.pTxMsg->Data[4] = msg->Min_Tem_Module;
    CAN1_Handler.pTxMsg->Data[5] = msg->Min_Tem_No;
		CAN1_Handler.pTxMsg->Data[6] = msg->Insul_Res.Byte;

    if (HAL_CAN_Transmit(&CAN1_Handler, 1) != HAL_OK) return 1;      //发送

    return 0;
}


/**
*******************************************************
*@brief can口接收数据查询
*@param[out]   buf:数据缓存区;
*@return      0,无数据被收到;其他,接收的数据长度;
*@note     none
*******************************************************
*/
u8 CAN1_Receive_Msg(u8 *buf)
{
    u32 i;

    if (HAL_CAN_Receive(&CAN1_Handler, CAN_FIFO0, 10) != HAL_OK) return 0;      //接收数据，超时时间设置为0

    for (i = 0; i < CAN1_Handler.pRxMsg->DLC; i++)
        buf[i] = CAN1_Handler.pRxMsg->Data[i];

    return CAN1_Handler.pRxMsg->DLC;
}
/**********************以下为调试上位机使用数据******************************/
/**
*******************************************************
*@brief 发送机柜中电芯电压数据
*@param[in]   msg：消息指针
*@param[in]   CAN_ID：目标ID
*@param[in]   len:数据长度(最大为8)
*@return      0,成功;其他,失败;
*@note     none
*******************************************************
*/
u8 CAN1_Send_CellV(Cell_Vol_TypeDef *msg, u32 CAN_ID, u8 len)
{
    CAN1_Handler.pTxMsg->ExtId = CAN_ID;      //扩展标识符(29位)
    CAN1_Handler.pTxMsg->IDE = CAN_ID_EXT;  //使用扩展帧
    CAN1_Handler.pTxMsg->RTR = CAN_RTR_DATA; //数据帧
    CAN1_Handler.pTxMsg->DLC = len;
    CAN1_Handler.pTxMsg->Data[0] = msg->Cell_1 & 0xFF;
    CAN1_Handler.pTxMsg->Data[1] = (msg->Cell_1 & 0xFF00) >> 8;
    CAN1_Handler.pTxMsg->Data[2] = msg->Cell_2 & 0xFF;
    CAN1_Handler.pTxMsg->Data[3] = (msg->Cell_2 & 0xFF00) >> 8;
    CAN1_Handler.pTxMsg->Data[4] = msg->Cell_3 & 0xFF;
    CAN1_Handler.pTxMsg->Data[5] = (msg->Cell_3 & 0xFF00) >> 8;
    CAN1_Handler.pTxMsg->Data[6] = msg->Cell_4 & 0xFF;
    CAN1_Handler.pTxMsg->Data[7] = (msg->Cell_4 & 0xFF00) >> 8;

    if (HAL_CAN_Transmit(&CAN1_Handler, 1) != HAL_OK) return 1;      //发送

    return 0;
}

/**
*******************************************************
*@brief 发送机柜中电芯温度数据
*@param[in]   msg：消息指针
*@param[in]   CAN_ID：目标ID
*@param[in]   len:数据长度(最大为8)
*@return      0,成功;其他,失败;
*@note     none
*******************************************************
*/
u8 CAN1_Send_CellT(Cell_Temper_TypeDef *msg, u32 CAN_ID, u8 len)
{
    CAN1_Handler.pTxMsg->ExtId = CAN_ID;      //扩展标识符(29位)
    CAN1_Handler.pTxMsg->IDE = CAN_ID_EXT;  //使用扩展帧
    CAN1_Handler.pTxMsg->RTR = CAN_RTR_DATA; //数据帧
    CAN1_Handler.pTxMsg->DLC = len;
    CAN1_Handler.pTxMsg->Data[0] = msg->Temp_1 & 0xFF;
    CAN1_Handler.pTxMsg->Data[1] = (msg->Temp_1 & 0xFF00) >> 8;
    CAN1_Handler.pTxMsg->Data[2] = msg->Temp_2 & 0xFF;
    CAN1_Handler.pTxMsg->Data[3] = (msg->Temp_2 & 0xFF00) >> 8;
    CAN1_Handler.pTxMsg->Data[4] = msg->Temp_3 & 0xFF;
    CAN1_Handler.pTxMsg->Data[5] = (msg->Temp_3 & 0xFF00) >> 8;
    CAN1_Handler.pTxMsg->Data[6] = msg->Temp_4 & 0xFF;
    CAN1_Handler.pTxMsg->Data[7] = (msg->Temp_4 & 0xFF00) >> 8;

    if (HAL_CAN_Transmit(&CAN1_Handler, 1) != HAL_OK) return 1;      //发送

    return 0;
}

/**
*******************************************************
*@brief 发送机柜中电芯均衡状态
*@param[in]   msg：消息指针
*@param[in]   CAN_ID：目标ID
*@param[in]   len:数据长度(最大为8)
*@return      0,成功;其他,失败;
*@note     none
*******************************************************
*/
u8 CAN1_Send_Banl(Cell_Banlance_TypeDef *msg, u32 CAN_ID, u8 len)
{
    CAN1_Handler.pTxMsg->ExtId = CAN_ID;      //扩展标识符(29位)
    CAN1_Handler.pTxMsg->IDE = CAN_ID_EXT;  //使用扩展帧
    CAN1_Handler.pTxMsg->RTR = CAN_RTR_DATA; //数据帧
    CAN1_Handler.pTxMsg->DLC = len;
	
    CAN1_Handler.pTxMsg->Data[0] = msg->Cell_banl & 0xFF;
    CAN1_Handler.pTxMsg->Data[1] = (msg->Cell_banl & 0xFF00) >> 8;
		CAN1_Handler.pTxMsg->Data[2] = msg->Cell_ban2 & 0xFF;
    CAN1_Handler.pTxMsg->Data[3] = (msg->Cell_ban2 & 0xFF00) >> 8;
		CAN1_Handler.pTxMsg->Data[4] = msg->Cell_ban3 & 0xFF;
    CAN1_Handler.pTxMsg->Data[5] = (msg->Cell_ban3 & 0xFF00) >> 8;
		CAN1_Handler.pTxMsg->Data[6] = msg->Cell_ban4 & 0xFF;
    CAN1_Handler.pTxMsg->Data[7] = (msg->Cell_ban4 & 0xFF00) >> 8;

    if (HAL_CAN_Transmit(&CAN1_Handler, 1) != HAL_OK) return 1;      //发送

    return 0;
}
/**
*******************************************************
*@brief 发送pack的故障信息
*@param[in]   msg：消息指针
*@param[in]   CAN_ID：目标ID
*@param[in]   len:数据长度(最大为8)
*@return      0,成功;其他,失败;
*@note     none
*******************************************************
*/
u8 CAN1_Send_AlmMeg(_Alarm_RegisterGroup *msg, u32 CAN_ID, u8 len)
{
    CAN1_Handler.pTxMsg->ExtId = CAN_ID;      //扩展标识符(29位)
    CAN1_Handler.pTxMsg->IDE = CAN_ID_EXT;  //使用扩展帧
    CAN1_Handler.pTxMsg->RTR = CAN_RTR_DATA; //数据帧
    CAN1_Handler.pTxMsg->DLC = len;
    CAN1_Handler.pTxMsg->Data[0] = msg->Serious_Alarm1.Word & 0xFF;
    CAN1_Handler.pTxMsg->Data[1] = (msg->Serious_Alarm1.Word & 0xFF00) >> 8;
    CAN1_Handler.pTxMsg->Data[2] = msg->Serious_Alarm2.Word & 0xFF;
    CAN1_Handler.pTxMsg->Data[3] = (msg->Serious_Alarm2.Word & 0xFF00) >> 8;
    CAN1_Handler.pTxMsg->Data[4] = msg->Slight_Alarm1.Word & 0xFF;
    CAN1_Handler.pTxMsg->Data[5] = (msg->Slight_Alarm1.Word & 0xFF00) >> 8;
    CAN1_Handler.pTxMsg->Data[6] = msg->Slight_Alarm2.Word & 0xFF;
    CAN1_Handler.pTxMsg->Data[7] = (msg->Slight_Alarm2.Word & 0xFF00) >> 8;

    if (HAL_CAN_Transmit(&CAN1_Handler, 1) != HAL_OK) return 1;      //发送

    return 0;
}

/**
*******************************************************
*@brief 发送pack中持续充、放电容量、时间信息
*@param[in]   msg：消息指针
*@param[in]   CAN_ID：目标ID
*@param[in]   len:数据长度(最大为8)
*@return      0,成功;其他,失败;
*@note     none
*******************************************************
*/
u8 CAN1_Send_RemTimeMeg(Remain_Mes_TypeDef *msg, u32 CAN_ID, u8 len)
{
    CAN1_Handler.pTxMsg->ExtId = CAN_ID;      //扩展标识符(29位)
    CAN1_Handler.pTxMsg->IDE = CAN_ID_EXT;  //使用扩展帧
    CAN1_Handler.pTxMsg->RTR = CAN_RTR_DATA; //数据帧
    CAN1_Handler.pTxMsg->DLC = len;
    CAN1_Handler.pTxMsg->Data[0] = msg->Char_Quantity & 0xFF;
    CAN1_Handler.pTxMsg->Data[1] = (msg->Char_Quantity & 0xFF00) >> 8;
    CAN1_Handler.pTxMsg->Data[2] = msg->Dischar_Quantity & 0xFF;
    CAN1_Handler.pTxMsg->Data[3] = (msg->Dischar_Quantity & 0xFF00) >> 8;
    CAN1_Handler.pTxMsg->Data[4] = msg->Char_Remain & 0xFF;
    CAN1_Handler.pTxMsg->Data[5] = (msg->Char_Remain & 0xFF00) >> 8;
    CAN1_Handler.pTxMsg->Data[6] = msg->Dischar_Remain & 0xFF;
    CAN1_Handler.pTxMsg->Data[7] = (msg->Dischar_Remain & 0xFF00) >> 8;

    if (HAL_CAN_Transmit(&CAN1_Handler, 1) != HAL_OK) return 1;      //发送

    return 0;
}

/**
*******************************************************
*@brief 发送pack中调试信息
*@param[in]   msg：消息指针，与之前不同，是u16指针，作为尝试
*@param[in]   CAN_ID：目标ID
*@param[in]   len:数据长度(最大为8)
*@return      0,成功;其他,失败;
*@note     none
*******************************************************
*/
u8 CAN1_Send_DebugMsg(u16 *msg, u32 CAN_ID, u8 len)
{
	CAN1_Handler.pTxMsg->ExtId = CAN_ID;      //扩展标识符(29位)
    CAN1_Handler.pTxMsg->IDE = CAN_ID_EXT;  //使用扩展帧
    CAN1_Handler.pTxMsg->RTR = CAN_RTR_DATA; //数据帧
    CAN1_Handler.pTxMsg->DLC = len;
    CAN1_Handler.pTxMsg->Data[0] = *msg & 0xFF;
    CAN1_Handler.pTxMsg->Data[1] = (*msg & 0xFF00) >> 8;
    CAN1_Handler.pTxMsg->Data[2] = *(msg + 1) & 0xFF;
    CAN1_Handler.pTxMsg->Data[3] = (*(msg + 1) & 0xFF00) >> 8;
    CAN1_Handler.pTxMsg->Data[4] = *(msg + 2) & 0xFF;
    CAN1_Handler.pTxMsg->Data[5] = (*(msg + 2) & 0xFF00) >> 8;
    CAN1_Handler.pTxMsg->Data[6] = *(msg + 3)& 0xFF;
    CAN1_Handler.pTxMsg->Data[7] = (*(msg + 4) & 0xFF00) >> 8;

    if (HAL_CAN_Transmit(&CAN1_Handler, 1) != HAL_OK) return 1;      //发送

    return 0;
}
